package core

import (
	"gitee.com/feimos/dm/utils"
	"log"
	"os"
	"strings"
)

func UpdateOneDocument(yamlContent *YamlContent, file string, writeYaml bool) error {

	root := yamlContent.Root
	path := utils.JoinPath(root, file)

	stat, err := os.Stat(path)

	if err != nil {
		return err
	}

	if stat.IsDir() {
		log.Printf("scan the content as the path of \"%v\" is a folder", file)
		return UpdateDocument(yamlContent, file)

	}

	fileInfo := CreateFileInfo(path, stat)

	ext := fileInfo.Ext
	name := fileInfo.Name

	status := yamlContent.UpdateItem(ext, fileInfo)

	if status == 2 {
		log.Printf("add document \"%v\" successfully\n", name)
	} else if status != -1 {
		log.Printf("update document \"%v\" successfully\n", name)
	} 

	if writeYaml {
		err := WriteYaml(yamlContent, true)
		if err != nil {
			return err
		}
	}

	return nil
}

func IsUnmatched(name string, matches []os.DirEntry) int {

	for index, item := range matches {
		if strings.ToLower(item.Name()) == strings.ToLower(name) {
			return index
		}
	}

	return -1
}

func RemoveUnusedContent(yamlContent *YamlContent, ext string, matches []os.DirEntry) error {

	if _, ok := yamlContent.Nodes[ext]; !ok {
		return nil
	}

	var removeList []int

	for index, info := range yamlContent.Nodes[ext] {
		checkingName := info.Name

		unmatchedIndex := IsUnmatched(checkingName, matches)

		if unmatchedIndex == -1 {
			removeList = append(removeList, index)
			log.Printf("remove unused document \"%v\"\n", checkingName)
		}

	}

	if len(removeList) > 0 {
		var newNode []*FileInfo
		for index, info := range yamlContent.Nodes[ext] {
			if !utils.IndexContains(index, removeList) {
				newNode = append(newNode, info)
			}
		}

		yamlContent.Nodes[ext] = newNode
	}

	return nil
}

func UpdateDocument(yamlContent *YamlContent, dir string) error {

	var ext string
	matches, err := os.ReadDir(dir)

	if err != nil {
		return err
	}

	for _, file := range matches {

		name := file.Name()
		ext = utils.GetExt(name)

		if file.IsDir() || name == DmFile || name == DmIgnoreFile {
			continue
		}

		err = UpdateOneDocument(yamlContent, utils.JoinPath(ext, name), false)
		if err != nil {
			return err
		}
	}

	err = RemoveUnusedContent(yamlContent, ext, matches)
	if err != nil {
		return err
	}

	err = WriteYaml(yamlContent, true)
	if err != nil {
		return err
	}

	return nil
}
